package com.yqg.manage.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.yqg.manage.controller.dto.ArchiveDTO;
import com.yqg.manage.entity.Archive;
import com.yqg.manage.mapper.ArchiveMapper;
import com.yqg.manage.service.IArchiveService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * ArchiveServiceImpl 服务实现类
 * @author suzhuang
 * @since 2023-07-05
 */
@Service
public class ArchiveServiceImpl extends MPJBaseServiceImpl<ArchiveMapper, Archive> implements IArchiveService {
    @Autowired
    ArchiveMapper archiveMapper;

    @Resource
    private IArchiveService archiveService;
    @Override
    public Map<Long, String> stageName() {
        Map<Long, String> map=new HashMap<>();
        for (Archive archive : archiveMapper.stageName()) {
            map.put(archive.getPstageId(),archive.getPstageName());
        }
    return map;
    }

    @Override
    public Map<Integer, String> documentName(int documentType, int pstageId) {
        Map<Integer,String> map=new HashMap<>();
        for (Archive archive : archiveMapper.documentName(documentType,pstageId)) {
            map.put(archive.getDocumentId(),archive.getDocumentName());
        }
    return map;
    }

    @Override
    public Map<String, String> documentTemp(int documentType, int pstageId) {
        Map<String,String> map=new HashMap<>();
        for (Archive archive : archiveMapper.documentTemp(documentType,pstageId)) {
            map.put(archive.getTemplateNo(),archive.getDocumentName());
        }
        return map;
    }

    /**
     * 获取文档列表的服务方法，根据文档类型和阶段ID进行查询，并进行分页处理。
     *
     * @param documentType 文档类型（外部1，内部0）
     * @param pstageId     阶段ID
     * @param page         当前页数
     * @param pageSize     每页记录数
     * @return 包含文档信息的DTO列表
     */
    @Override
    public Page<ArchiveDTO> getDocumentList(int documentType, int pstageId, int page, int pageSize) {
        // 创建查询条件包装器
        LambdaQueryWrapper<Archive> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Archive::getDocumentType, documentType);
        wrapper.eq(Archive::getPstageId, pstageId);

        // 指定返回的字段
        wrapper.select(Archive::getDocumentId,Archive::getDocumentName, Archive::getTemplateNo, Archive::getTemplateFile, Archive::getUpdateTime,
                Archive::getTemplateDesc, Archive::getIsDelete);

        // 分页查询
        Page<Archive> archivePage = new Page<>(page, pageSize);
        archiveService.page(archivePage, wrapper);

        // 使用辅助方法将Page<Archive>转换为Page<ArchiveDTO>
        Page<ArchiveDTO> archiveDTOPage = convertPageToDTO(archivePage, ArchiveDTO.class);
        // 打印输出结果
        System.out.println(archiveDTOPage);
        return archiveDTOPage;
    }

    /**
     * 将源对象转换为目标类型的DTO对象，通过BeanUtil.copyProperties方法进行属性复制。
     *
     * @param source     源对象
     * @param targetType 目标DTO类型
     * @param <T>        源对象类型
     * @param <R>        目标DTO类型
     * @return 转换后的目标DTO对象
     */
    private <T, R> R convertToDTO(T source, Class<R> targetType) {
        try {
            // 使用反射创建目标DTO对象实例
            R target = targetType.getDeclaredConstructor().newInstance();
            // 将源对象的属性复制到目标DTO对象
            BeanUtil.copyProperties(source, target, true);
            return target;
        } catch (Exception e) {
            e.printStackTrace();
            // 可以根据实际情况进行异常处理或日志记录
            return null;
        }
    }
    /**
     * 将包含源对象的Page转换为包含目标对象的新Page。
     *
     * @param sourcePage 原始的Page对象，其中包含源对象的记录列表
     * @param targetType 目标对象的Class类型，用于进行属性复制
     * @param <S>        源对象类型
     * @param <T>        目标对象类型
     * @return 转换后的新Page对象，其中包含目标对象的记录列表
     */
    private <S, T> Page<T> convertPageToDTO(Page<S> sourcePage, Class<T> targetType) {
        // 获取原始Page对象中的记录列表
        List<S> sourceList = sourcePage.getRecords();

        // 使用Stream API进行对象转换，使用方法引用复制属性
        List<T> targetList = sourceList.stream()
                .map(source -> convertToDTO(source, targetType))
                .collect(Collectors.toList());

        // 创建新的Page对象，并设置记录列表为转换后的列表
        Page<T> targetPage = new Page<>(sourcePage.getCurrent(), sourcePage.getSize(), sourcePage.getTotal());
        targetPage.setRecords(targetList);

        return targetPage;
    }


}
